//
//  KDLibrary.m
//  Amber
//
//  Created by Keith Duncan on 05/03/2008.
//  Copyright 2008 thirty-three. All rights reserved.
//

#import "AFLibrary.h"

#import "AFSourceNode.h"

NSString *const AFLibraryUnknownLocation = @"Unknown Location";

@interface AFLibrary ()
@property(readwrite, retain) AFSourceNode *rootNode;
@end

@implementation AFLibrary

@synthesize path=_path;
@synthesize delegate;
@synthesize rootNode=_rootNode;

- (id)initWithFilePath:(NSString *)path {
	[self init];
	
	self.path = path;
	
	return self;
}

- (void)dealloc {
	[_path release];
	[_rootNode release];
	
	[super dealloc];
}

- (NSBundle *)bundle {
	return [delegate bundle];
}

- (BOOL)isLoaded {
	return _loaded;
}

- (void)setPath:(NSString *)path {
	if (self.isLoaded) [NSException raise:NSInternalInconsistencyException format:@"-[%@ %s], cannot set the library location once the library has been loaded. You must instantiate a new library object.", NSStringFromClass([self class]), _cmd, nil];
	
	[_path autorelease];
	_path = [path copy];
}

- (BOOL)loadAndReturnError:(NSError **)error {
	if ([self isLoaded]) return YES;
	
	BOOL libraryFound = NO;
	BOOL requestPath = [self.path isEqualToString:AFLibraryUnknownLocation];
	
	if (!requestPath) {
		NSMutableArray *searchPaths = [[NSMutableArray alloc] init];
		if (self.path != nil) [searchPaths addObject:_path];
		[searchPaths addObject:[(id)self expectedPath]];
		if ([self respondsToSelector:@selector(additionalSearchPaths)]) [searchPaths addObjectsFromArray:[(id)self additionalSearchPaths]];
		
		for (NSString *path in searchPaths) {
			if (!AFFileExistsAtPath(path)) continue;
			
			libraryFound = YES;
			self.path = path;
			
			break;
		}
		
		[searchPaths release];
	}
		
	if ((requestPath || !libraryFound) && (delegate != nil && [delegate respondsToSelector:@selector(requestPathForLibrary:)])) {
		[delegate requestPathForLibrary:self];
	}
	
	if (!AFFileExistsAtPath(_path)) {
		if (error != NULL) *error = [NSError errorWithDomain:NSCocoaErrorDomain code:NSFileNoSuchFileError userInfo:[NSDictionary dictionaryWithObjectsAndKeys:@"Could not find a library to load.", NSLocalizedDescriptionKey, nil]];
		return NO;
	}
	
	return YES;
}

- (NSMenuItem *)_createMenuItemForNode:(AFSourceNode *)node {
	NSMenuItem *nodeMenuItem = [[NSMenuItem alloc] init];
	
	[nodeMenuItem setImage:node.image];
	[nodeMenuItem setTitle:[node.name stringByAppendingElipsisAfterCharacters:30]];
	
	[nodeMenuItem setEnabled:((delegate != nil && [delegate respondsToSelector:@selector(library:isObjectSelectable:)]) ? [delegate library:self isObjectSelectable:node] : YES)];
	[nodeMenuItem setIndentationLevel:([[node indexPath] length] - 1)];
	
	return nodeMenuItem;
}

- (void)_addChildNodes:(AFSourceNode *)node to:(NSMenu *)menu {
	for (AFSourceNode *currentNode in [node childNodes]) {
		NSMenuItem *currentNodeMenuItem = [self _createMenuItemForNode:currentNode];
		
		[menu addItem:currentNodeMenuItem];
		[self _addChildNodes:currentNode to:menu];
		
		[currentNodeMenuItem release];
	}
}

- (NSMenu *)sourceMenu {
	NSMenu *sourceMenu = [[NSMenu alloc] init];
	[sourceMenu setAutoenablesItems:NO];
	
	for (AFSourceNode *rootChild in [_rootNode childNodes]) {
		[self _addChildNodes:rootChild to:sourceMenu];
		if (rootChild != [[_rootNode childNodes] lastObject]) [sourceMenu addItem:[NSMenuItem separatorItem]];
	}
	
	return [sourceMenu autorelease];
}

@end
